﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;

namespace elevator
{
    class Elevator
    {
        int currentFloor;
        int Xcoord;
        int Ycoord;
        string doorStatus = "closed";
        string movingDirection = "stopped";
        Panel p;
        Panel liftUIp; 
        bool occupied = false;

        List<System.Drawing.Image> doorAnimationImages;
        List<Image> doorCloseAnimationImages;

        List<Person> occupant1 = new List<Person>();
        List<Person> occupant2 = new List<Person>();

        ArrayList commands;

        public Elevator(Panel panel, Panel luip)
        {
            currentFloor = 1;
            p = panel;
            liftUIp = luip;

            Xcoord = panel.Location.X;
            Ycoord = panel.Location.Y;

            commands = new ArrayList();

            doorAnimationImages = new List<System.Drawing.Image>();
            doorCloseAnimationImages = new List<Image>();
            addImagesToAnimationList();
        }

        public double getWeight()
        {
            double p1 = 0.00;
            double p2 = 0.00; 
            if (occupant1.Count != 0)
            {
                p1 = occupant1[0].getWeight(); 
            }
            if (occupant2.Count != 0)
            {
                p2 = occupant2[0].getWeight(); 
            }
            double weight = p1 + p2;
            return weight; 
        }

        public void addImagesToAnimationList()
        {
            doorAnimationImages.Add(Properties.Resources.closed);
            doorAnimationImages.Add(Properties.Resources._01);
            doorAnimationImages.Add(Properties.Resources._02);
            doorAnimationImages.Add(Properties.Resources._03);
            doorAnimationImages.Add(Properties.Resources._04);
            doorAnimationImages.Add(Properties.Resources._05);
            doorAnimationImages.Add(Properties.Resources._06);
            doorAnimationImages.Add(Properties.Resources._07);
            doorAnimationImages.Add(Properties.Resources._08);
            doorAnimationImages.Add(Properties.Resources._09);
            doorAnimationImages.Add(Properties.Resources._10);
            doorAnimationImages.Add(Properties.Resources._11);
            doorAnimationImages.Add(Properties.Resources._012);
            doorAnimationImages.Add(Properties.Resources._13);
            doorAnimationImages.Add(Properties.Resources._14);
            doorAnimationImages.Add(Properties.Resources._15);
            doorAnimationImages.Add(Properties.Resources._16);
            doorAnimationImages.Add(Properties.Resources._17);
            doorAnimationImages.Add(Properties.Resources._18);
            doorAnimationImages.Add(Properties.Resources._19);
            doorAnimationImages.Add(Properties.Resources._20);
            doorAnimationImages.Add(Properties.Resources._21);
            doorAnimationImages.Add(Properties.Resources._22);
            doorAnimationImages.Add(Properties.Resources.opened);


            foreach (Image x in doorAnimationImages)
            {
                doorCloseAnimationImages.Add(x);
            }

            doorCloseAnimationImages.Reverse();

        }

        public void addNewCommand(String command)
        {
            if (!(commands.Contains(command)))
            {
                commands.Add(command);
            }
        }

        public void emptyCommands()
        {
            commands.Clear();
        }

        public Panel getPanel()
        {
            return p; 
        }

        public void removeCommand(String command)
        {
            commands.Remove(command); 
        }

        public String getNextCommand()
        {
            if (commands.Count != 0)
            {
                return commands[0].ToString();
            }
            else
            {
                return ""; 
            }
        }

        public int getCurrentFloor()
        {
            return currentFloor;
        }

        public void setCurrentFloor(int floor)
        {
            currentFloor = floor;
        }

        public void setDoors(String status)
        {
            doorStatus = status;
        }

        public string getDoorStatus()
        {
            return doorStatus;
        }

        public void setMovingDirection(String status)
        {
            movingDirection = status;
        }

        public string getMovingDirection()
        {
            return movingDirection; 
        }

        public bool isOccupied()
        {
            return occupied;
        }

        public void setOccupied(bool condition)
        {
            occupied = condition;
        }


        /* Reset the elevator to 0,0 when GUI parameters are changed */
        public void reset(int X, int Y)
        {
            setX(X);
            setY(Y);
            setCurrentFloor(1);
            setDoors("closed");
            emptyCommands();
            p.BackgroundImage = doorAnimationImages[0];
        }

   
        /* Move lift animation */
        public void moveLift(string direction)
        {
            if (direction.Equals("up"))
            {
                Thread animationThread = new Thread(new ThreadStart(moveUp));
                animationThread.Start();
            }
            else if (direction.Equals("down"))
            {
                Thread animationThread = new Thread(new ThreadStart(moveDown));
                animationThread.Start();
            }
        }
        private void moveUp()
        {
            //if (getDoorStatus().Equals("open"))
            //{
            //    closeDoors();
            //}
            Thread.Sleep(20); // THIS IS IMPORTANT - IT NEEDS 20ms TO CHANGE STATUS OTHERWISE IT WILL SKIP THE REST OF THE LOOP
            while (getDoorStatus().Equals("closing"))
            {
                // Bide your time elevator
            }
            //int i = 0;
            //while (getDoorStatus().Equals("closed"))
            //{
                //while (i <= 300)
                //{
                    Thread.Sleep(10);
                    this.setY(Ycoord - 1);
                    //i++;
                //}
                //if (i == 301)
                //{
                  //  openDoors();
                //}
            //}
        }
        private void moveDown()
        {
           if (getDoorStatus().Equals("open"))
            {
                closeDoors();
            }
            Thread.Sleep(20); // THIS IS IMPORTANT - IT NEEDS 20ms TO CHANGE STATUS OTHERWISE IT WILL SKIP THE REST OF THE LOOP
            while (getDoorStatus().Equals("closing"))
            {
                // Bide your time elevator
            }
            //int i = 0;
            //while (getDoorStatus().Equals("closed"))
            //{
            //    while (i <= 300)
            //    {
                    Thread.Sleep(10);
                    this.setY(Ycoord + 1);
                //    i++;
                //}
                //if (i == 301)
                //{
                //    openDoors();
                //}
            //}
        }
        public void setY(int newY)
        {
            Ycoord = newY;
        }
        public void setX(int newX)
        {
            Xcoord = newX;
        }
        public void updateLiftPosition()
        {
            p.Location = new Point(Xcoord, Ycoord);
        }

        /* Opening doors animation */
        public void openDoors()
        {
            Thread animationThread = new Thread(new ThreadStart(animateOpening));
            animationThread.Start(); 
        }
        private void animateOpening()
        {
            if (getDoorStatus().Equals("closed"))
            {
                int i = 0;
                setDoors("opening");
                while (i <= 23)
                {
                    p.BackgroundImage = doorAnimationImages[i];
                    Thread.Sleep(40);
                    i++;
                }
                setDoors("open");
            }
        }

        /* Closing doors animation */
        public void closeDoors()
        {
            Thread animationThread = new Thread(new ThreadStart(animateClosing));
            animationThread.Start(); 
        }
        private void animateClosing()
        {
            if (getDoorStatus().Equals("open"))
            {
                int i = 0;
                setDoors("closing");
                while (i <= 23)
                {
                    p.BackgroundImage = doorCloseAnimationImages[i];
                    Thread.Sleep(40);
                    i++;
                }
                setDoors("closed");  
            }
        }


        /* Add occupants */
        public void addOccupant(int occupantNumber, Person p)
        {
            if (occupantNumber == 1)
            {
                occupant1.Add(p);
            }
            else if (occupantNumber == 2)
            {
                occupant2.Add(p); 
            }
        }
        /* Remove occupants */
        public void removeOccupant(int occupantNumber, Person p)
        {
            if (occupantNumber == 1)
            {
                occupant1.Remove(p);
            }
            else if (occupantNumber == 2)
            {
                occupant2.Remove(p);
            }
        }

        /* Get occupant list */
        public List<Person> getOccupantList(int occupantNumber)
        {
            if (occupantNumber == 1)
            {
                return occupant1;
            }
            else if (occupantNumber == 2)
            {
                return occupant2;
            }
            return new List<Person>(); 
        }

        public void emptyList(int listNumber)
        {
            if (listNumber == 1)
            {
                occupant1.Clear();
            }
            else if (listNumber == 2)
            {
                occupant2.Clear(); 
            }
        }
    }
}
